package com.eshin.anno;

import java.util.List;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component("privilegeAnnoAspect") 
public class PrivilegeAnnoAspect {
    /**
     * 用户本身的权限
     */
    private List<FirmPrivilege> privileges;

    public List<FirmPrivilege> getPrivileges() {
        return privileges;
    }

    public void setPrivileges(List<FirmPrivilege> privileges) {
        this.privileges = privileges;
    }
    @Pointcut("@annotation(com.eshin.anno.PrivilegeInfo)")
    public void PrivilegeInfoPointcut() {
    }
    
    @Pointcut("@annotation(privilegeInfo)")
    public void PrivilegeInfoPointcutWithArgs(PrivilegeInfo privilegeInfo) {
    }
    
//    @Pointcut("@annotation(privilegeInfo)")
//    public void PrivilegeInfoPointcut(PrivilegeInfo privilegeInfo) {
//    }
//    
//    JoinPoint需要放在第一个参数
    @Before(value="this(firmService1)",argNames="firmService1")
    public void beforeWithParam4(JoinPoint joinPoint,FirmService firmService1) {
    	//this对象应该是一个代理对象
    	System.out.println(this.getClass().getName()+"==============before 传递this对象： " + this.getClass());
    	System.out.println(firmService1.getClass().getName()+"==============before 传递this对象： " + firmService1.getClass());
    	System.out.println( joinPoint.getSignature().getName());
    }
    
    @After("target(firmService1)")
    public void afterWithParam4(JoinPoint joinPoint,FirmService firmService1) {
    	//this对象应该是一个代理对象
    	System.out.println(this.getClass().getName()+"==============@After 传递this对象： " + this.getClass());
    	System.out.println(firmService1.getClass().getName()+"==============@After 传递this对象： " + firmService1.getClass());
    	System.out.println( "=============================================="+joinPoint.getSignature().getName()+"==============================================");
    }
    
    /**
     * beanname为firmService1,且方法参数为id的方法
     * @param id
     */
    @Before(value="bean(firmService1) && args(id)", argNames="id")
    public void beforeWithParam2(String id) {
    	System.out.println(this.getClass().getName()+" ID is : " + id);
    }
//  @Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()")
//    @Around("PrivilegeInfoPointcut()")
//    public void methodsAnnotated(final ProceedingJoinPoint joinPoint) throws Throwable {
    @Around("PrivilegeInfoPointcutWithArgs(privilegeInfo)")
    public void methodsAnnotated(final ProceedingJoinPoint joinPoint,PrivilegeInfo privilegeInfo) throws Throwable {
    	
    	System.out.println("开始执行："+joinPoint.getSignature().getName()+" ");
    	/**
         * 1.获取访问目标方法应该具备的权限
         *  为解析目标方法的PrivilegeInfo注解，根据我们定义的解析器，需要得到：目标类的class形式　方法的名称
         */
        Class<? extends Object> targetClass = joinPoint.getTarget().getClass();
        String methodName = joinPoint.getSignature().getName();
        //得到该方法的访问权限
        String methodAccess = PrivilegeAnnotationParse.parse(targetClass, methodName);
        /*
         * 2.遍历用户的权限，看是否拥有目标方法对应的权限
         */
        boolean isAccessed = false;
        for (FirmPrivilege firmPrivilege : privileges) {
            /*
             * 如果目标方法没有使用PrivilegeInfo注解，则解析出来的权限字符串就为空字符串
             * 则默认用户拥有这个权限
             */
            if ("".equals(methodAccess)) {
                isAccessed = true;
                break;
            }
            /*
             * 用户原有权限列表中有的权限与目标方法上PrivilegeInfo注解配置的权限进行匹配
             */
            if (firmPrivilege.getValue() != null && 
                    firmPrivilege.getValue().equalsIgnoreCase(methodAccess)) {
                isAccessed = true;
                break;
            }
        }
        /*
         * 3.如果用户拥有权限，则调用目标方法　，如果没有，则不调用目标方法，只给出提示
         */
        if (isAccessed) {
            joinPoint.proceed();//调用目标方法
        } else {
            System.out.println("你没有权限");
        }
        System.out.println("结束执行："+joinPoint.getSignature().getName()+" ");
    	
    }
}
